[BLKTAP] Blktapctrl: Add asynchronous watch on dom0 name entry for blktapctrl on...
authorjchesterfield@dhcp92.uk.xensource.com <jchesterfield@dhcp92.uk.xensource.com>
Thu, 5 Oct 2006 09:55:13 +0000 (10:55 +0100)
committerjchesterfield@dhcp92.uk.xensource.com <jchesterfield@dhcp92.uk.xensource.com>
Thu, 5 Oct 2006 09:55:13 +0000 (10:55 +0100)
Signed-off-by: Julian Chesterfield <julian@xensource.com>
tools/blktap/drivers/blktapctrl.c
tools/blktap/lib/blktaplib.h
tools/blktap/lib/xenbus.c
tools/blktap/lib/xs_api.c
tools/blktap/lib/xs_api.h

index 60d999c78d1fbd8e27d2105ee4379362aaacbc46..690c5de97fab7697d546a65656ec40e11152dff4 100644 (file)
@@ -669,6 +669,7 @@ int main(int argc, char *argv[])
                goto open_failed;
        }
 
+
  retry:
        /* Set up store connection and watch. */
        h = xs_daemon_open();
@@ -682,15 +683,14 @@ int main(int argc, char *argv[])
                 } else goto open_failed;
        }
        
-       ret = add_blockdevice_probe_watch(h, "Domain-0");
-       if (ret != 0) {
+       ret = setup_probe_watch(h);
+       if (ret < 0) {
                DPRINTF("Failed adding device probewatch\n");
-                if (count < MAX_ATTEMPTS) {
-                        count++;
-                        sleep(2);
-                        xs_daemon_close(h);
-                        goto retry;
-                } else goto open_failed;
+               xs_daemon_close(h);
+               goto open_failed;
+       } else {
+               DPRINTF("Added probe %s\n", 
+                      (ret ? "ASYNCHRONOUSLY":"SYNCHRONOUSLY"));
        }
 
        ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
index 7f1d4f1a94c29b233eefd37cf4a7daf012b9e0a7..456a368786853ef610fa2e05df145b1e7659c9c2 100644 (file)
@@ -193,8 +193,8 @@ typedef struct msg_pid {
 #define CTLMSG_PID_RSP     10
 
 /* xenstore/xenbus: */
-extern int add_blockdevice_probe_watch(struct xs_handle *h, 
-                                       const char *domname);
+#define DOMNAME "Domain-0"
+int setup_probe_watch(struct xs_handle *h);
 int xs_fire_next_watch(struct xs_handle *h);
 
 
index 91cdd005366be02f7a5dd6435e028ff241f967b5..95b5f602abbfe310297898cd44b368f87c4513fa 100644 (file)
@@ -356,17 +356,12 @@ static void ueblktap_probe(struct xs_handle *h, struct xenbus_watch *w,
  *are created, we initalise the state and attach a disk.
  */
 
-int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname)
+int add_blockdevice_probe_watch(struct xs_handle *h, const char *domid)
 {
-       char *domid, *path;
+       char *path;
        struct xenbus_watch *vbd_watch;
        int er;
        
-       domid = get_dom_domid(h, domname);
-
-       DPRINTF("%s: %s\n", 
-               domname, (domid != NULL) ? domid : "[ not found! ]");
-       
        asprintf(&path, "/local/domain/%s/backend/tap", domid);
        if (path == NULL) 
                return -ENOMEM;
@@ -385,3 +380,69 @@ int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname)
        }
        return 0;
 }
+
+/*
+ *Asynch callback to check for /local/domain/<DOMID>/name
+ */
+void check_dom(struct xs_handle *h, struct xenbus_watch *w, 
+              const char *bepath_im) {
+       char *domid = NULL;
+
+       domid = get_dom_domid(h);
+       if (domid) {
+               add_blockdevice_probe_watch(h, domid);
+               free(domid);
+               unregister_xenbus_watch(h, w);
+       }
+       return; 
+}
+
+/*
+ *We must wait for xend to register /local/domain/<DOMID>
+ */
+int watch_for_domid(struct xs_handle *h)
+{
+       struct xenbus_watch *domid_watch;
+       char *path = NULL;
+       int er;
+
+       asprintf(&path, "/local/domain");
+       if (path == NULL) 
+               return -ENOMEM;
+
+       domid_watch = (struct xenbus_watch *)malloc(sizeof(struct xenbus_watch));
+       if (!domid_watch) {
+               DPRINTF("ERROR: unable to malloc domid_watch [%s]\n", path);
+               return -EINVAL;
+       }       
+       domid_watch->node     = path;
+       domid_watch->callback = check_dom;
+       er = register_xenbus_watch(h, domid_watch);
+       if (er == 0) {
+               DPRINTF("ERROR: adding vbd probe watch %s\n", path);
+               return -EINVAL;
+       }
+       if (path == NULL) 
+               return -ENOMEM; 
+       return 1;
+}
+
+int setup_probe_watch(struct xs_handle *h)
+{
+       char *domid = NULL, *path;
+       int ret;
+       
+       domid = get_dom_domid(h);
+
+       if (!domid) {
+                /*Asynchronous path*/
+               ret = watch_for_domid(h);
+               goto finish;
+       } else {
+               /*Synchronous path*/
+               ret = add_blockdevice_probe_watch(h, domid);
+               free(domid);
+       }
+ finish:
+       return ret;
+}
index 054e9c850a752ad31872304d547acb95fc937f80..6d6a5fdfba7414bed5aef368a987cf8d0afa1c2c 100644 (file)
@@ -165,7 +165,7 @@ int xs_exists(struct xs_handle *h, const char *path)
  * This assumes that the domain name we are looking for is unique. 
  * Name parameter Domain-0 
  */
-char *get_dom_domid(struct xs_handle *h, const char *name)
+char *get_dom_domid(struct xs_handle *h)
 {
        char **e, *val, *domid = NULL;
        unsigned int num, len;
@@ -187,7 +187,7 @@ char *get_dom_domid(struct xs_handle *h, const char *name)
                if (val == NULL)
                        continue;
                
-               if (strcmp(val, name) == 0) {
+               if (strcmp(val, DOMNAME) == 0) {
                        /* match! */
                        asprintf(&path, "/local/domain/%s/domid", e[i]);
                        domid = xs_read(h, xth, path, &len);
index c4183a2dded46b9209e3b7050e1165009f2521c9..34430dcc48abc2b8681fc122034a87b5e9080746 100644 (file)
@@ -42,7 +42,7 @@ int xs_gather(struct xs_handle *xs, const char *dir, ...);
 int xs_printf(struct xs_handle *h, const char *dir, const char *node, 
              const char *fmt, ...);
 int xs_exists(struct xs_handle *h, const char *path);
-char *get_dom_domid(struct xs_handle *h, const char *name);
+char *get_dom_domid(struct xs_handle *h);
 int convert_dev_name_to_num(char *name);
 int register_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);
 int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);